import hashlib
import json
import os
import time

from django.http import HttpResponse, JsonResponse, HttpRequest, FileResponse
from django.shortcuts import render, redirect
from django.urls import path, re_path
from utils.route.wrappers import set_route_protects, json_post_checker, login_permission
from django.core.cache import cache
from mainApp.models import *
from django.views.decorators.csrf import csrf_exempt
from hashlib import md5
from apCelery.celeryApp import app as celery_app
from django.conf import settings
from mainApp.instances import SingleTest


def hello(request):
    # try:
    with SingleTest() as obj:
        # time.sleep(15)
        obj.count += 1
        obj.age = 12
        obj.save()
        data = {
            "count": obj.count,
            "age": obj.age,
            "info": obj.info,
            "instance_id": obj.instance_id
        }
        return JsonResponse(data)


@set_route_protects(minute=100)
@login_permission
def index(request):
    return HttpResponse("<h1>this is django project</h1>")


@csrf_exempt
@set_route_protects(minute=60)
def login(request):
    """
    登录 生成session
    :param request:
    :return:
    """
    if request.method == 'POST':
        if request.content_type == 'application/json':
            data = json.loads(request.body)
        else:
            data = request.POST
        username: str = data['username']
        password: str = data['password']
        hasher = md5()
        hasher.update((password + settings.SECRET_KEY).encode('utf-8'))
        password_hashed: str = hasher.hexdigest()

        user = WebUser.objects.filter(username=username).first()
        if user is None:
            return JsonResponse({'code': 400, 'message': '用户不存在'})
        if user.password != password_hashed:
            return JsonResponse({'code': 400, 'message': '密码错误'})

        request.session['username'] = username
        return redirect('mainApp:index')
    else:
        return render(request, 'login.html')


def logout(request):
    request.session.clear()
    return redirect('mainApp:index')


@csrf_exempt
@set_route_protects(minute=20)
def register(request):
    """
    注册路由
    get返回注册页面 post注册
    :param request:
    :return:
    """
    if request.method == 'POST':
        data = json.loads(request.body) if request.content_type == 'application/json' else request.POST
        username = data.get('username')
        password = data.get('password')
        user = WebUser.objects.filter(username=username).exists()
        if user:
            return JsonResponse({'code': 500, 'message': f'{username} 用户名已存在'})

        hashed_password = hashlib.md5((password + settings.SECRET_KEY).encode('utf-8')).hexdigest()
        user = WebUser(username=username, password=hashed_password)
        WebUser.save(user)
        return JsonResponse({'code': 200, 'message': None})
    else:
        return render(request, 'register.html')


@json_post_checker({"ip_address": str, "type": str, "route": str})
def flush_route_protect(request, data: dict = None):
    ip_address: str = data.pop("ip_address")
    route: str = data.get("route")
    _type: str = data.pop("type")
    if _type not in ["minute", "hour", "day"]:
        return JsonResponse({"code": 500, "message": f"未知类型：'{_type}'"})

    if route is not None:
        RouteProtect.objects.filter(ip_address=ip_address, route_url=route).update(**{f"per_{_type}": 0})
    else:
        RouteProtect.objects.filter(ip_address=ip_address).update(**{f"per_{_type}": 0})
    return JsonResponse({"code": 200, "message": "success"})


def celery_hello(request: HttpRequest):
    job = celery_app.send_task("test")
    return JsonResponse({"code": 200, "message": None, "data": {"job_id": job.id}})


def celery_result(request: HttpRequest, job_id: str):
    result = celery_app.AsyncResult(job_id)
    if result.status == "SUCCESS":
        return JsonResponse({"code": 200, "message": None, "data": {"result": result.result}})
    return JsonResponse({"code": 200, "message": result.status})


def file_download(request: HttpRequest, file_name: str):
    _path = os.getcwd() + '/static/files/' + file_name
    if os.path.exists(_path):
        with open(_path, 'r') as f:
            resp = FileResponse(f.read())
            resp['Content-Disposition'] = 'attachment; filename="file.txt"'
            return resp
    else:
        return JsonResponse({"code": 404, "message": "文件不存在"})


def test(request: HttpRequest):
    cache.set('test', 'test')


urlpatterns = [
    path('', index, name='index'),
    path('hello', hello, name='hello'),
    path('login', login, name='login'),
    path('logout', logout, name='logout'),
    path('register', register, name='register'),

    path('protect/flush', flush_route_protect, name='protect_flush'),
    path('celery', celery_hello, name='celery_hello'),
    path('celery/result/<str:job_id>', celery_result, name='celery_result'),

    path('download/file/<str:file_name>', file_download, name='file_download')
]
